package dao

import (
	"context"
	"fmt"

	"bmember/internal/object"
	"bmember/pkg/util"

	"bmember/internal/model"
)

// BalanceDao 余额记录 dao
type BalanceDao interface {
	// CreateBalanceLog 创建余额流水
	CreateBalanceLog(ctx context.Context, bLog *model.BalanceLog) (int64, error)
	// GetBalanceLogByPayOrderNo 根据支付单号获取余额记录
	GetBalanceLogByPayOrderNo(ctx context.Context, payOrderNo string) ([]*model.BalanceLog, error)
	// GetBalanceLogByRefundOrderNo 根据退款单号单号获取余额记录
	GetBalanceLogByRefundOrderNo(ctx context.Context, refundOrderNo string) ([]*model.BalanceLog, error)
	// GetBalanceLogsByMembersGroup 加载余额记录
	GetBalanceLogsByMembersGroup(ctx context.Context, memberIds []int64, groupId int64, pg object.Pagination) ([]*model.BalanceLog, uint32, error)
}

type bLogDaoImpl struct {
	*DaoBase
	name string
}

var bDao BalanceDao

// InitBalanceDao 初始化 dao 层
func InitBalanceDao() {
	bDao = &bLogDaoImpl{
		DaoBase: daoBase,
		name:    "balance_log_dao",
	}
}

// GetBalanceLogDao 获得余额日志 dao 层
func GetBalanceLogDao() BalanceDao {
	return bDao
}

// CreateBalanceLog 创建余额流水
func (dao *bLogDaoImpl) CreateBalanceLog(ctx context.Context, bLog *model.BalanceLog) (int64, error) {
	if bLog == nil {
		return 0, nil
	}
	param := []interface{}{
		bLog.BrandId,
		bLog.StoreId,
		bLog.GroupId,
		bLog.CardId,
		bLog.MemberId,
		bLog.AccId,
		bLog.BalType,
		bLog.Amount,
		bLog.PayOrderNo,
		bLog.RefundOrderNo,
		bLog.EmpId,
		bLog.Remark,
	}
	query := "INSERT INTO balance_log (brand_id, store_id, group_id, card_id, member_id, acc_id, bal_type, " +
		"amount, pay_order_no, refund_order_no, emp_id, remark, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())"
	aff, err := dao.db.PgExec(ctx, "id", query, param...)
	if err != nil {
		return 0, err
	}
	lastId, _ := aff.GetLastId()
	return lastId, nil
}

// GetBalanceLogByPayOrderNo 根据支付单号获取余额记录
func (dao *bLogDaoImpl) GetBalanceLogByPayOrderNo(ctx context.Context, payOrderNo string) ([]*model.BalanceLog, error) {
	if payOrderNo == "" {
		return nil, nil
	}
	var bLogs []*model.BalanceLog
	query := "SELECT * FROM balance_log WHERE pay_order_no=? AND deleted_at=0"
	err := dao.db.Query(ctx, &bLogs, query, payOrderNo)
	return bLogs, err
}

// GetBalanceLogByRefundOrderNo 根据退款单号单号获取余额记录
func (dao *bLogDaoImpl) GetBalanceLogByRefundOrderNo(ctx context.Context, refundOrderNo string) ([]*model.BalanceLog, error) {
	if refundOrderNo == "" {
		return nil, nil
	}
	var bLogs []*model.BalanceLog
	query := "SELECT * FROM balance_log WHERE refund_order_no=? AND deleted_at=0"
	err := dao.db.Query(ctx, &bLogs, query, refundOrderNo)
	return bLogs, err
}

// GetBalanceLogsByMembersGroup 加载余额记录
func (dao *bLogDaoImpl) GetBalanceLogsByMembersGroup(ctx context.Context, memberIds []int64, groupId int64, pg object.Pagination) ([]*model.BalanceLog, uint32, error) {
	if len(memberIds) == 0 {
		return nil, 0, nil
	}
	where := fmt.Sprintf("FROM balance_log WHERE member_id IN (%s) AND group_id=%d AND deleted_at=0 ", util.SqlIDsJoin(memberIds), groupId)
	total, err := dao.CountNum(ctx, where)
	if err != nil {
		return nil, 0, err
	}
	query := fmt.Sprintf("SELECT id, brand_id, group_id, member_id, bal_type, amount, created_at %s ORDER BY created_at DESC %s", where, pg.GetDbOffset())
	var iLogs []*model.BalanceLog
	err = dao.db.Query(ctx, &iLogs, query)
	return iLogs, total, err
}
